package lion.web.interceptors.rewrite;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import lion.framework.core.web.path.PathVar;

/**
 * @author lion
 * @mail hl_0074@sina.com
 * @date 2011-10-12
 *
 */
public class RewriteConf {

	private static List<RewriteRule> rewriteRules = new ArrayList<>();
	private static Map<String, String> defines = new HashMap<>();
	private static boolean enabled = false;

	private static Pattern pattern = Pattern.compile("\\$\\{(.*?)\\}");
	private static boolean inited = false;

	public static List<RewriteRule> getRewriteRules() {

		if (!inited) {
			init();
		}

		return rewriteRules;
	}

	private synchronized static void init() {

		if (inited) { return; }

		Document doc = null;
		try {
			SAXReader reader = new SAXReader();
			doc = reader.read(RewriteConf.class.getResourceAsStream("/linkrewrite.xml"));
		} catch (Exception e) {
		}
		if (doc != null) {
			parse(doc);
		}
		inited = true;
	}

	private static void parse(Document doc) {

		Node node = doc.selectSingleNode("/links/enable");

		if ("true".equals(node.getText())) {
			enabled = true;
		}

		List<Element> nodes = doc.selectNodes("/links/define");
		for (Element n : nodes) {

			String name = n.attributeValue("name");
			String value = n.attributeValue("value");

			if (StringUtils.isNotBlank(name)) {
				defines.put(name, value);
			}
		}

		nodes = doc.selectNodes("/links/rule");
		for (Element e : nodes) {

			String from = null;
			String to = null;
			boolean last = false;

			Attribute attribute = e.attribute("last");
			if (attribute != null && "true".equals(attribute.getText())) {
				last = true;
			}

			Node tmp = e.selectSingleNode("from");
			if (tmp == null) {
				continue;
			}
			from = tmp.getText();
			if (StringUtils.isBlank(from)) {
				continue;
			}
			tmp = e.selectSingleNode("to");
			if (tmp == null) {
				continue;
			}
			to = tmp.getText();
			if (StringUtils.isBlank(to)) {
				continue;
			}

			if (!defines.isEmpty()) {
				from = replaceDefinedVars(from);
				to = replaceDefinedVars(to);
			}

			from = PathVar.replacePathVars(from.trim());
			to = PathVar.replacePathVars(to.trim());
			rewriteRules.add(new RewriteRule(from, to, last));
		}
	}

	private static String replaceDefinedVars(String str) {

		if (str.indexOf("${") < 0) { return str; }
		Matcher m = pattern.matcher(str);
		StringBuffer sbu = new StringBuffer();
		while (m.find()) {
			String v = defines.get(m.group(1));
			if (v != null) {
				m.appendReplacement(sbu, v);
			}
		}
		m.appendTail(sbu);
		return sbu.toString();
	}

	public static boolean isEnabled() {

		return enabled;
	}
}
